﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml;
using Devv.Core.Erroo;
using Devv.Core.Utils;

namespace Devv.FreshTracker
{
	public class Options
	{
		#region Internal XML properties (private)

		private static String XmlPath { get { return App.DataPath + "Config.xml"; } }
		private static XmlDocument Xml { get; set; }

		#endregion

		#region Properties

		public static Boolean FirstRun { get; set; }

		public static String CurrentVersion { get; set; }
		public static String Email { get; set; }
		public static String ApiUrl { get; set; }
		public static String ApiToken { get; set; }
		public static String UserCompany { get; set; }
		public static String UserName { get; set; }
		public static Int64 UserId { get; set; }
		public static Boolean CheckUpdates { get; set; }
		public static Boolean StartMinimized { get; set; }
		public static Boolean ShowMini { get; set; }
		public static Boolean ShowNotes { get; set; }
		public static Boolean TopMost { get; set; }
		public static Boolean ReportErrors { get; set; }
		public static Boolean Debug { get; set; }
		public static Boolean EnableRules { get; set; }
		public static Double Opacity { get; set; }
		public static Double Round { get; set; }
		public static Double AutoStop { get; set; }
		public static Int32 PosX { get; set; }
		public static Int32 PosY { get; set; }
		public static Int64 LastProjectId { get; set; }
		public static Int64 LastTaskId { get; set; }

		#endregion

		#region Helper properties

		public static Boolean IsLoginSet
		{
			get { return (ApiUrl.Length >= 5 && ApiToken.Length >= 5); }
		}

		#endregion

		#region Name Value collections

		public static List<DoubleItem> TimerRoundCollection { get; set; }
		public static List<DoubleItem> TimerAutoStopCollection { get; set; }

		#endregion

		#region Loading

		public static void Create()
		{
			XmlDocument x = new XmlDocument();

			XmlNode root = x.CreateElement("FreshTracker");
			XmlNode config = x.CreateElement("Config");

			XmlNode version = x.CreateElement("CurrentVersion");
			XmlNode email = x.CreateElement("Email");
			XmlNode apiurl = x.CreateElement("ApiUrl");
			XmlNode apitoken = x.CreateElement("ApiToken");
			XmlNode usercompany = x.CreateElement("UserCompany");
			XmlNode username = x.CreateElement("UserName");
			XmlNode userid = x.CreateElement("UserId");
			XmlNode checkupdates = x.CreateElement("CheckUpdates");
			XmlNode startmin = x.CreateElement("StartMini");
			XmlNode showmini = x.CreateElement("ShowMini");
			XmlNode shownotes = x.CreateElement("ShowNotes");
			XmlNode topmost = x.CreateElement("TopMost");
			XmlNode reporterrors = x.CreateElement("ReportErrors");
			XmlNode debug = x.CreateElement("Debug");
			XmlNode rules = x.CreateElement("EnableRules");
			XmlNode opacity = x.CreateElement("Opacity");
			XmlNode autostop = x.CreateElement("AutoStop");
			XmlNode round = x.CreateElement("Round");
			XmlNode posX = x.CreateElement("X");
			XmlNode posY = x.CreateElement("Y");
			XmlNode projectid = x.CreateElement("LastProjectId");
			XmlNode taskid = x.CreateElement("LastTaskId");

			version.InnerText = AssemblyUtil.GetFriendlyVersion(Assembly.GetEntryAssembly());
			checkupdates.InnerText = "true";
			startmin.InnerText = "false";
			showmini.InnerText = "true";
			shownotes.InnerText = "true";
			topmost.InnerText = "true";
			reporterrors.InnerText = "true";
			debug.InnerText = "false";
			rules.InnerText = "false";
			opacity.InnerText = "0.8";
			autostop.InnerText = "0";
			round.InnerText = "0";
			posX.InnerText = "-1";
			posY.InnerText = "-1";
			projectid.InnerText = "0";
			taskid.InnerText = "0";

			config.AppendChild(version);
			config.AppendChild(email);
			config.AppendChild(apiurl);
			config.AppendChild(apitoken);
			config.AppendChild(usercompany);
			config.AppendChild(username);
			config.AppendChild(userid);
			config.AppendChild(checkupdates);
			config.AppendChild(startmin);
			config.AppendChild(showmini);
			config.AppendChild(shownotes);
			config.AppendChild(topmost);
			config.AppendChild(reporterrors);
			config.AppendChild(debug);
			config.AppendChild(rules);
			config.AppendChild(opacity);
			config.AppendChild(autostop);
			config.AppendChild(round);
			config.AppendChild(posX);
			config.AppendChild(posY);
			config.AppendChild(projectid);
			config.AppendChild(taskid);

			root.AppendChild(config);
			x.AppendChild(root);

			String dir = Path.GetDirectoryName(XmlPath);

			if (!Directory.Exists(dir))
			{
				Directory.CreateDirectory(dir);
			}

			x.Save(XmlPath);

			Maintenance.Log("Created new options file.");
		}

		public static void Load()
		{
			TimerRoundCollection = new List<DoubleItem>
			                       	{
			                       		new DoubleItem(0, Messages.DoNotRound),
			                       		new DoubleItem(0.05, "3 " + Messages.Minutes),
			                       		new DoubleItem(0.10, "6 " + Messages.Minutes),
			                       		new DoubleItem(0.20, "12 " + Messages.Minutes),
			                       		new DoubleItem(0.25, "15 " + Messages.Minutes),
			                       		new DoubleItem(0.50, "30 " + Messages.Minutes)
			                       	};

			TimerAutoStopCollection = new List<DoubleItem>
										{
			                          		new DoubleItem(0, Messages.Never),
			                          		new DoubleItem(30, "30 " + Messages.Minutes),
			                          		new DoubleItem(60, "60 " + Messages.Minutes),
			                          		new DoubleItem(90, "90 " + Messages.Hours),
			                          		new DoubleItem(120, "2 " + Messages.Hours),
			                          		new DoubleItem(240, "4 " + Messages.Hours),
			                          		new DoubleItem(480, "8 " + Messages.Hours)
			                          	};

			Xml = new XmlDocument();

			if (!File.Exists(XmlPath))
			{
				Create();
				FirstRun = true;
			}

			try
			{
				Xml.Load(XmlPath);

				CurrentVersion = GetConfig("CurrentVersion");
				Email = GetConfig("Email");
				ApiUrl = GetConfig("ApiUrl");
				ApiToken = GetConfig("ApiToken");
				CheckUpdates = GetConfig("CheckUpdates", true);
				StartMinimized = GetConfig("StartMinimized", true);
				ShowMini = GetConfig("ShowMini", true);
				ShowNotes = GetConfig("ShowNotes", true);
				TopMost = GetConfig("TopMost", true);
				ReportErrors = GetConfig("ReportErrors", true);
				Debug = GetConfig("Debug", false);
				EnableRules = GetConfig("EnableRules", false);
				Opacity = GetConfig("Opacity", 0.8);
				AutoStop = GetConfig("AutoStop", 0);
				Round = GetConfig("Round", 0);
				PosX = GetConfig("X", 0);
				PosY = GetConfig("Y", 0);
				LastProjectId = GetConfig("LastProjectId", 0);
				LastTaskId = GetConfig("LastTaskId", 0);
			}
			catch (Exception ex)
			{
				ErrorHandler.Handle(ex, Messages.ErrorCouldNotLoadConfig);
			}

			Config.DoShowDialog = Debug;

			Maintenance.Log("Loaded options.");
		}

		private static String GetConfig(String key)
		{
			XmlNode n = Xml.SelectSingleNode("//Config/" + key);

			if (n == null)
			{
				return String.Empty;
			}

			return n.InnerText;
		}

		private static Double GetConfig(String key, Double value)
		{
			String result = GetConfig(key);

			if (String.IsNullOrEmpty(result))
			{
				return value;
			}

			return Convert.ToDouble(result);
		}

		private static Int32 GetConfig(String key, Int32 value)
		{
			String result = GetConfig(key);

			if (String.IsNullOrEmpty(result))
			{
				return value;
			}

			return Convert.ToInt32(result);
		}

		private static Boolean GetConfig(String key, Boolean value)
		{
			String result = GetConfig(key);

			if (String.IsNullOrEmpty(result))
			{
				return value;
			}

			return DataUtil.GetBoolean(result);
		}

		#endregion

		#region Save

		public static void Save()
		{
			SetConfig("CurrentVersion", CurrentVersion);
			SetConfig("Email", Email);
			SetConfig("ApiUrl", ApiUrl);
			SetConfig("ApiToken", ApiToken);
			SetConfig("UserCompany", UserCompany);
			SetConfig("UserName", UserName);
			SetConfig("UserId", UserId);
			SetConfig("CheckUpdates", CheckUpdates);
			SetConfig("StartMinimized", StartMinimized);
			SetConfig("ShowMini", ShowMini);
			SetConfig("ShowNotes", ShowNotes);
			SetConfig("TopMost", TopMost);
			SetConfig("ReportErrors", ReportErrors);
			SetConfig("Debug", Debug);
			SetConfig("EnableRules", EnableRules);
			SetConfig("Opacity", Opacity);
			SetConfig("Round", Round);
			SetConfig("AutoStop", AutoStop);
			SetConfig("PosX", PosX);
			SetConfig("PosY", PosY);
			SetConfig("LastProjectId", LastProjectId);
			SetConfig("LastTaskId", LastTaskId);

			Xml.Save(XmlPath);

			Maintenance.Log("Saved options.");
		}

		private static void SetConfig(String key, Double value)
		{
			SetConfig(key, value.ToString());
		}

		private static void SetConfig(String key, Int32 value)
		{
			SetConfig(key, value.ToString());
		}

		private static void SetConfig(String key, Int64 value)
		{
			SetConfig(key, value.ToString());
		}

		private static void SetConfig(String key, Boolean value)
		{
			SetConfig(key, value.ToString());
		}

		private static void SetConfig(String key, String value)
		{
			XmlNode n = Xml.SelectSingleNode("//Config/" + key);

			if (n == null)
			{
				n = Xml.CreateElement(key);
				Xml.SelectSingleNode("//Config").AppendChild(n);
			}

			n.InnerText = value;
		}

		#endregion
	}
}